//
//  BaseWebViewController.swift
//  ShangYouNews
//
//  Created by 王坤 on 2017/12/3.
//  Copyright © 2017年 baymax. All rights reserved.
//

import WebKit
import HandyJSON

//MARK: BaseWebViewController
open class BaseWebViewController: BaseViewController, BaseMessageHandleDelegate {
    
    /// scriptmsg泛型闭包
    //    typealias ScriptMsg<T : ScriptMessageEnumProtocol, K> = (_ str : String, _ type : T ,_ info : K) -> Void
    
    var strUrl : String!
    var myWebView  : WKWebView!
    var actiView   = UIActivityIndicatorView.init(activityIndicatorStyle: .gray)
    
    var userContentController = WKUserContentController()
    var scriptMessageHandler = BaseMessageHandler()
    //允许横屏
    var horizontalHideNavBar = false
    
    fileprivate var btnClose: UIButton!
    
    override open func viewDidLoad() {
        super.viewDidLoad()
        self.showBackButton()
        
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = false
        config.mediaPlaybackRequiresUserAction = false
        scriptMessageHandler.delegate = self
        userContentController.add(scriptMessageHandler, name: "ShangYou")
        config.userContentController = userContentController
        
        myWebView = WKWebView(frame: CGRect.zero, configuration: config)
        myWebView.allowsBackForwardNavigationGestures = true
        myWebView.navigationDelegate = self
        self.view.addSubview(myWebView)
        myWebView.snp.makeConstraints { (make) in
            make.edges.equalTo(UIEdgeInsets.zero)
        }
        
        self.view.addSubview(actiView)
        actiView.snp.makeConstraints { [unowned self](make) in
            make.centerX.equalTo(self.view)
            make.centerY.equalTo(self.view).offset(-32)
        }
        SystemNotifer.addObserver(observer: self, selector: #selector(appActiveState(_:)), notiItem: .EnterBackground)
        SystemNotifer.addObserver(observer: self, selector: #selector(appActiveState(_:)), notiItem: .EnterForeground)
    }
    
    @objc func appActiveState(_ noti: Notification) {
        let name = noti.name.rawValue
        switch name {
        case SystemNotifer.EnterBackground.rawValue:
            print("进入后台")
            AudioPlayer.shared.pauseAllPlayer()
        case SystemNotifer.EnterForeground.rawValue:
            
            print("进入前台")
        default:
            print("其他")
        }
    }
    
    func initCloseBtn() {
        btnClose = UIButton.init(type: .custom)
        btnClose.frame = CGRect.init(x: 0, y: 0, width: 60, height: 30)
        btnClose.contentHorizontalAlignment = .left
        btnClose.addTarget(self, action: #selector(backButtonClose), for: .touchUpInside)
        btnClose.titleLabel?.font = UIFont.systemFont(ofSize: 14)
        btnClose.setTitle("关闭", for: .normal)
        btnClose.setTitleColor(UIColor.black, for: .normal)
    }
    
    @objc func backButtonClose(){
        myWebView?.scrollView.delegate = nil
        super.backButtonClick()
    }
    
    override func backButtonClick() {
        if myWebView.canGoBack {
            myWebView.goBack()
            if isFirst {
                isFirst = false
                self.setNavButton(loc: .left, btns: [btnBack,btnClose])
            }
        } else {
            self.myWebView = nil
            //            super.backButtonClick()
            if self.navigationController != nil {
                //                CATransaction.begin()
                //                CATransaction.setCompletionBlock({[weak self]() in
                //                    print(CFGetRetainCount(self))
                //                })
                self.navigationController?.popViewController(animated: true)
                //                CATransaction.commit()
            } else {
                self.dismiss(animated: true, completion: nil)
            }
        }
    }
    override open func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }
    
    deinit {
        myWebView?.scrollView.delegate = nil
        userContentController.removeScriptMessageHandler(forName: "ShangYou")
        print("ssssssssssssssssssss")
    }
    
    public func clearWKWebViewCache()
    {
        // iOS9开始提供了清理WKWebView的API
        if #available(iOS 9.0, *) {
            let websiteDataTypes = Set([WKWebsiteDataTypeDiskCache,
                                        WKWebsiteDataTypeMemoryCache,
                                        WKWebsiteDataTypeOfflineWebApplicationCache,
                                        WKWebsiteDataTypeCookies,
                                        WKWebsiteDataTypeSessionStorage,
                                        WKWebsiteDataTypeLocalStorage,
                                        WKWebsiteDataTypeWebSQLDatabases,
                                        WKWebsiteDataTypeIndexedDBDatabases])
            
            let date = Date(timeIntervalSince1970: 0)
            WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes, modifiedSince: date, completionHandler: {})
        } else {
            print("系统不是ios9以上")
        }
    }
    
    func didReciveMessage(_ userContentController: WKUserContentController, _ message: ScriptMessageData) -> Bool {
        guard let enumValue = ScriptMessageEnum(rawValue: message.action) else {
            return false
        }
        switch enumValue {
        case .mClearWebCache:
            self.clearWKWebViewCache();
            return true
        case .mClosePage:
            self.navigationController?.popViewController(animated: true)
            return true
        case .mTelephone:
            if message.data.count > 0 {
                UIApplication.shared.openURL(URL(string: "telprompt://\(message.data)")!)
            }
            return true
        case .mClientId:
//            myWebView.evaluateJavaScript("setDriverId(\"\(UDID)\", \"\(APPKEY)\")", completionHandler: { (imgInfo, error) in
            
//            })
            return true
        }
    }
    
    override open func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
}

//MARK: - 横竖屏
extension BaseWebViewController {
    override open var shouldAutorotate: Bool {
        return true
    }
    
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .allButUpsideDown
    }
    
    override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .portrait
    }
    
    override open func willRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
        if horizontalHideNavBar {
            if (toInterfaceOrientation == .landscapeLeft || toInterfaceOrientation == .landscapeRight) {
                UIApplication.shared.setStatusBarHidden(true, with: .slide)
                self.navigationController?.setNavigationBarHidden(true, animated: true)
            } else {
                UIApplication.shared.setStatusBarHidden(false, with: .slide)
                self.navigationController?.setNavigationBarHidden(false, animated: true)
            }
        }
    }
}


//MARK: - WKNavigationDelegate, UIScrollViewDelegate
extension BaseWebViewController: WKNavigationDelegate, UIScrollViewDelegate {
    ///主要是为了适配网页允许放大缩小
    public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return nil
    }
    
    ///页面开始加载时调用
    public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        actiView.isHidden = false
        actiView.startAnimating()
        myWebView.scrollView.delegate = self
    }
    
    // 当内容开始返回时调用
    public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        print("网页开始返回数据")
    }
    
    /// 页面加载完成之后调用
    public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        actiView.isHidden = true
        actiView.stopAnimating()
        myWebView.scrollView.delegate = nil
        
        let titleStr = myWebView.title ?? "上游新闻"
        var titlenum = 0
        if Device.size() == .iphone4  && titleStr.count > 10{ ///iphone 4 十个字
            titlenum = 7
        }else if Device.size() == .iphone5 && titleStr.count > 12{///iphone 5 12个字
            titlenum = 9
        }else if Device.size() == .iphone6 && titleStr.count > 15{///iphone 6 15个字
            titlenum = 12
        }else if Device.size() == .iphone6p && titleStr.count > 20{///iphone 6P 20个字
            titlenum = 17
        }
        
        if titlenum > 0 {
            let start = titleStr.startIndex
            let end = titleStr.index(start, offsetBy: titlenum)
//            let range  = start ..< end
            
            self.title = String(titleStr[..<end])//.substring(with: range) + "..."
        } else {
            self.title = titleStr
        }
    }
    // 页面加载失败时调用
    public func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        actiView.isHidden = true
        actiView.stopAnimating()
        
        //self.view.showHud(title: "页面加载失败", showIndicator: false, touchBack: false, time: 1)
        print("网页加载失败")
    }
    
    public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        print("--->>\(#function)")
        /// 如果是返回就执行这个操作
        if navigationAction.navigationType == .backForward {
            if isFirst && webView.canGoBack{
                isFirst = false
                self.setNavButton(loc: .left, btns: [btnBack,btnClose])
            }
        }
    }
    
    public func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        print("--->>\(#function)")
        decisionHandler(.allow)
    }
    
}

//MARK: - WKUIDelegate
extension BaseWebViewController: WKUIDelegate {
    ///alert
    public func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        
        let alertController = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "确认", style: .default, handler: { (action) in
            completionHandler()
        }))
        self.present(alertController, animated: true)
    }
    
    public func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        let alertController = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "取消", style: .default, handler: { (action) in
            completionHandler(false)
        }))
        alertController.addAction(UIAlertAction(title: "确定", style: .default, handler: { (action) in
            completionHandler(true)
        }))
        self.present(alertController, animated: true, completion: nil)
    }
    
    public func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
        let alertController = UIAlertController(title: prompt, message: "", preferredStyle: .alert)
        alertController.addTextField { (txtView) in
            txtView.text = defaultText
        }
        alertController.addAction(UIAlertAction(title: "完成", style: .default, handler: { (action) in
            completionHandler(alertController.textFields?[0].text ?? "")
        }))
        self.present(alertController, animated: true, completion: nil)
    }
}

//MARK: BaseMessageHandler
struct ScriptMessageData: HandyJSON {
    var action = ""
    var data = ""
}

public protocol ScriptMessageEnumProtocol{}

enum ScriptMessageEnum: String ,ScriptMessageEnumProtocol{
    case mClearWebCache
    case mClosePage
    case mTelephone
    case mClientId
}

protocol BaseMessageHandleDelegate :NSObjectProtocol {
    func didReciveMessage(_ userContentController: WKUserContentController, _ message: ScriptMessageData) -> Bool
}


class BaseMessageHandler: NSObject,WKScriptMessageHandler {
    weak var delegate : BaseMessageHandleDelegate?
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        let body = (message.body as? String) ?? ""
        guard let data = JSONDeserializer<ScriptMessageData>.deserializeFrom(json: body) else {
            return
        }
        _ = delegate?.didReciveMessage(userContentController, data)
    }
}

